﻿using Newtonsoft.Json;
using System;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace HenrryTools.WinFormTools
{
    public partial class JsonWinForm : Form
    {
        public JsonWinForm()
        {
            InitializeComponent();
        }
        /// <summary>
        /// 缓存并且判断最常使用得密钥  IsClipboard默认为True复制
        /// </summary>
        public void DefaultLoadValue(string Message, bool IsClipboard)
        {
            Properties.Settings.Default.JSONWinFormRoot = txtRoot.Text;//保存在Settings
            Properties.Settings.Default.Save();//保存

            if (IsClipboard)
            {
                Clipboard.SetDataObject(txtRoot.Text);//复制
            }

            labMessage.Text = Message;
            labMessage.ForeColor = Color.Green;
        }
        /// <summary>
        /// 压缩
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnComPress_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtRoot.Text))
            {
                labMessage.Text = "输入为空，请输入!";
                labMessage.ForeColor = Color.Red; return;
            }
            try
            {
                StringBuilder Text = new StringBuilder();
                using (StringReader reader = new StringReader(txtRoot.Text))
                {
                    int ch = -1;
                    int lastch = -1;
                    bool isQuoteStart = false;
                    while ((ch = reader.Read()) > -1)
                    {
                        if ((char)lastch != '\\' && (char)ch == '\"')
                        {
                            if (!isQuoteStart)
                            {
                                isQuoteStart = true;
                            }
                            else
                            {
                                isQuoteStart = false;
                            }
                        }
                        if (!Char.IsWhiteSpace((char)ch) || isQuoteStart)
                        {
                            Text.Append((char)ch);
                        }
                        lastch = ch;
                    }
                }
                txtRoot.Text = Text.ToString();
                DefaultLoadValue("JSON压缩成功，剪切板已复制!", true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
           
        }
        /// <summary>
        /// 格式化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSend_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtRoot.Text))
            {
                labMessage.Text = "输入为空，请输入!";
                labMessage.ForeColor = Color.Red; return;
            }
            //格式化json字符串
            JsonSerializer serializer = new JsonSerializer();
            TextReader tr = new StringReader(txtRoot.Text);
            JsonTextReader jtr = new JsonTextReader(tr);
            try
            {
                object obj = serializer.Deserialize(jtr);
                if (obj != null)
                {
                    StringWriter textWriter = new StringWriter();
                    JsonTextWriter jsonWriter = new JsonTextWriter(textWriter)
                    {
                        Formatting = Formatting.Indented,
                        Indentation = 4,
                        IndentChar = ' '
                    };
                    serializer.Serialize(jsonWriter, obj);
                    txtRoot.Text = textWriter.ToString();
                    DefaultLoadValue("老铁，这个JSON格式，没毛病。", true);
                }
            }
            catch (Exception ex)
            {
                labMessage.Text = "JSON异常:" + ex.Message;
                labMessage.ForeColor = Color.Red;
            }
        }
        /// <summary>
        /// 清空
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDelete_Click(object sender, EventArgs e)
        {
            txtRoot.Text = "";
        }
        /// <summary>
        /// 动态监测行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtRoot_TextChanged(object sender, EventArgs e)
        {
            ShowLineNum();
            SyncSrollLocation();
        }
        /// <summary>
        /// 滚动条滚动时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtRoot_VScroll(object sender, EventArgs e)
        {
            SyncSrollLocation();
        }

        private void txtRoot_Resize(object sender, EventArgs e)
        {
            ShowLineNum();
            SyncSrollLocation();
        }
        //行号 生成显示  这里rtxtNum用的 RichTextBox，也可以用其它
        private void ShowLineNum()
        {
            rtxtNum.Text = "";


            //计算行高，行数
            int linesLength = 0;
            var pFirst = txtRoot.GetPositionFromCharIndex(0);
            var pEnd = txtRoot.GetPositionFromCharIndex(txtRoot.Text.Length);
            if (pEnd.Y > pFirst.Y)
            {
                var pSecondLine = txtRoot.GetPositionFromCharIndex(txtRoot.GetFirstCharIndexFromLine(1));
                var lineHeight = pSecondLine.Y - pFirst.Y;
                linesLength = (pEnd.Y - pFirst.Y) / lineHeight;
            }
            else
            {
                linesLength = 1;
            }

            //生成行数
            for (var i = 0; i < linesLength; i++)
            {
                rtxtNum.AppendText(i + 1 + "\n");
            }

            //行号右对齐
            rtxtNum.SelectAll();
            rtxtNum.SelectionAlignment = HorizontalAlignment.Right;
        }

        //上次滚动位置 行
        private int _scrollToLine = 0;


        //同步滚动
        private void SyncSrollLocation()
        {
            //首行首字符初始位置
            var p = new Point(1, 1);


            //计算行高
            int lineHeight = 0;
            var pFirst = txtRoot.GetPositionFromCharIndex(0);//首行位置
            var pEnd = txtRoot.GetPositionFromCharIndex(txtRoot.Text.Length);//最后一行位置
            if (pEnd.Y > pFirst.Y)//排除只有一行的情况
            {
                var pSecondLine = txtRoot.GetPositionFromCharIndex(txtRoot.GetFirstCharIndexFromLine(1));
                lineHeight = pSecondLine.Y - pFirst.Y;
            }

            //滚动高度 即首行位置移动高度    
            int scrollHeight = p.Y - pFirst.Y;

            //滚动到的行的位置  由于滚动大都并非整行滚动 所以四舍五入 ***程序的误差就在这里
            if (scrollHeight == 0 && scrollHeight == 0) { return; }
            var scrollTolineIndex = (int)Math.Round((double)(scrollHeight / lineHeight), MidpointRounding.AwayFromZero);


            if (_scrollToLine != scrollTolineIndex)
            {
                _scrollToLine = scrollTolineIndex;
                var sStart = rtxtNum.GetFirstCharIndexFromLine(scrollTolineIndex);//左侧行号 当前滚动到行 首字符位置
                if (sStart >= 0)
                {
                    rtxtNum.SelectionStart = sStart;
                    rtxtNum.SelectionLength = 0;
                    rtxtNum.ScrollToCaret();
                }
            }
        }
        /// <summary>
        /// 加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void JsonWinForm_Load(object sender, EventArgs e)
        {
            if (!string.IsNullOrWhiteSpace(Properties.Settings.Default.JSONWinFormRoot))
            {
                txtRoot.Text = Properties.Settings.Default.JSONWinFormRoot;
            }
        }
    }
}
